﻿import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from datetime import datetime, timedelta

# 设置中文字体
plt.rcParams['font.sans-serif'] = ['SimHei']  # 使用黑体
plt.rcParams['axes.unicode_minus'] = False    # 解决负号显示问题

print("=" * 50)
print("Pandas 综合使用示例")
print("=" * 50)

# 1. 创建示例数据集
print("\n1. 创建示例数据集")
np.random.seed(42)  # 确保可重复性

# 创建日期范围
dates = pd.date_range('2023-01-01', periods=100, freq='D')

# 创建示例数据
data = {
    '日期': dates,
    '销售额': np.random.normal(1000, 200, 100).round(2),
    '客户数': np.random.poisson(50, 100),
    '产品类别': np.random.choice(['电子产品', '服装', '食品', '家居'], 100),
    '促销活动': np.random.choice([True, False], 100, p=[0.3, 0.7])
}

# 创建 DataFrame
df = pd.DataFrame(data)
print("数据框形状:", df.shape)
print("\n前5行数据:")
print(df.head())

# 2. 数据探索与基本信息
print("\n2. 数据探索与基本信息")
print("\n数据框信息:")
print(df.info())
print("\n数值列描述性统计:")
print(df.describe())
print("\n产品类别分布:")
print(df['产品类别'].value_counts())

# 3. 数据筛选与查询
print("\n3. 数据筛选与查询")
# 筛选促销期间的数据
promo_data = df[df['促销活动'] == True]
print(f"促销期间数据量: {len(promo_data)}")

# 查询销售额高于平均值的记录
above_avg = df[df['销售额'] > df['销售额'].mean()]
print(f"销售额高于平均值的记录数: {len(above_avg)}")

# 多条件筛选
high_sales_electronics = df[(df['产品类别'] == '电子产品') & (df['销售额'] > 1200)]
print(f"电子产品高销售额记录数: {len(high_sales_electronics)}")

# 4. 数据分组与聚合
print("\n4. 数据分组与聚合")
# 按产品类别分组并计算平均销售额
category_stats = df.groupby('产品类别').agg({
    '销售额': ['mean', 'sum', 'count'],
    '客户数': 'mean'
})
print("按产品类别的统计:")
print(category_stats)

# 计算每周销售额
df['周'] = df['日期'].dt.isocalendar().week
weekly_sales = df.groupby('周')['销售额'].sum()
print("\n每周销售额:")
print(weekly_sales.head())

# 5. 数据清洗与处理
print("\n5. 数据清洗与处理")
# 复制数据以避免修改原始数据
df_clean = df.copy()

# 检查缺失值
print("缺失值统计:")
print(df_clean.isnull().sum())

# 添加一些缺失值用于演示
df_clean.loc[::10, '销售额'] = np.nan
print(f"\n添加缺失值后，销售额缺失数: {df_clean['销售额'].isnull().sum()}")

# 填充缺失值
df_clean['销售额'].fillna(df_clean['销售额'].mean(), inplace=True)
print(f"填充后销售额缺失数: {df_clean['销售额'].isnull().sum()}")

# 6. 数据转换与创建新列
print("\n6. 数据转换与创建新列")
# 计算客单价
df['客单价'] = df['销售额'] / df['客户数']
df['客单价'] = df['客单价'].round(2)

# 创建销售额等级列
df['销售额等级'] = pd.cut(
    df['销售额'], 
    bins=[0, 800, 1000, 1200, float('inf')],
    labels=['低', '中', '高', '很高']
)

print("添加新列后的数据:")
print(df[['日期', '销售额', '客户数', '客单价', '销售额等级']].head())

# 7. 时间序列处理
print("\n7. 时间序列处理")
# 将日期设置为索引
df_time = df.set_index('日期')

# 计算7天移动平均
df_time['销售额_7天平均'] = df_time['销售额'].rolling(window=7).mean()

# 重采样为周数据
weekly_df = df_time.resample('W').agg({
    '销售额': 'sum',
    '客户数': 'sum'
})
weekly_df['平均客单价'] = weekly_df['销售额'] / weekly_df['客户数']

print("周数据重采样:")
print(weekly_df.head())

# 8. 数据可视化
print("\n8. 数据可视化")
fig, axes = plt.subplots(2, 2, figsize=(15, 10))
fig.suptitle('Pandas 数据分析可视化', fontsize=16)

# 销售额随时间变化
df.plot(x='日期', y='销售额', ax=axes[0, 0], title='销售额随时间变化')
axes[0, 0].tick_params(axis='x', rotation=45)

# 产品类别销售额分布
category_sales = df.groupby('产品类别')['销售额'].sum()
category_sales.plot(kind='bar', ax=axes[0, 1], title='各产品类别总销售额')

# 促销与非促销对比
promo_effect = df.groupby('促销活动')['销售额'].mean()
promo_effect.plot(kind='bar', ax=axes[1, 0], title='促销活动对销售额的影响')

# 销售额箱线图
df.boxplot(column='销售额', by='产品类别', ax=axes[1, 1])
axes[1, 1].set_title('各产品类别销售额分布')

plt.tight_layout()
plt.show()

# 9. 数据输出
print("\n9. 数据输出")
# 保存处理后的数据
df.to_csv('sales_data_processed.csv', index=False, encoding='utf-8-sig')
print("数据已保存到 sales_data_processed.csv")

# 创建Excel写入器
with pd.ExcelWriter('sales_analysis.xlsx') as writer:
    df.to_excel(writer, sheet_name='原始数据', index=False)
    category_stats.to_excel(writer, sheet_name='产品类别统计')
    weekly_df.to_excel(writer, sheet_name='周数据')

print("分析结果已保存到 sales_analysis.xlsx")

print("\n" + "=" * 50)
print("Pandas 综合示例完成")
print("=" * 50)